package com.example.train.common.utils;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.json.JSONUtil;
import com.example.train.common.config.security.filter.PreventRequestReplayFilter;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

@Slf4j
public class SignUtil {

    public static String sign(String str,String signSecret) {
        //eg: 104c6b96dc67f11c4d2e4acb37b05f86
        Assert.notBlank(signSecret);
        Assert.notBlank(str);
        HMac mac = new HMac(HmacAlgorithm.HmacMD5, signSecret.getBytes());
        return mac.digestHex(str);
    }

    /**
     * 多用于JSON body转换为消息摘要
     * @param str
     * @return
     */
    public static String digester(String str){
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        String s = String.valueOf(chars);
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String digestHex = md5.digestHex(s);
        return digestHex;
    }

    public static boolean verify(String signStr, String origStr,String signSecret) {
        if (StrUtil.isBlank(signStr) || StrUtil.isBlank(origStr) || StrUtil.isBlank(signSecret)) {
            return false;
        }
        String sign = sign(origStr, signSecret);
        log.info("verify generate sign: {}, signSecret:{}", sign,signSecret);
        return sign.equals(signStr);
    }

    public static String generateGetPlainText(String url,String timestamp){

        int index = url.indexOf("?");

        String signStr = URLUtil.getPath(url) + "?timestamp=" + timestamp;
        if (index > -1) {
            String paramStr = url.substring(index+1);

            if (StrUtil.isNotBlank(paramStr)) {
                String[] params = paramStr.split(PreventRequestReplayFilter.API_PARAMETER_SEPARATOR);
                Arrays.sort(params);
                paramStr = StrUtil.join(PreventRequestReplayFilter.API_PARAMETER_SEPARATOR, params);
                signStr += PreventRequestReplayFilter.API_PARAMETER_SEPARATOR + paramStr;
            }
        }

        return signStr;
    }

    public static String generatePostPlainText(String url,String timestamp,Object paramObj){
        String signStr = generateGetPlainText(url, timestamp);

        if (paramObj != null) {
            String jsonStr = JSONUtil.toJsonStr(paramObj);
            log.info("JSON body:{}",jsonStr);
            signStr += PreventRequestReplayFilter.API_PARAMETER_SEPARATOR + "body=" + digester(jsonStr);
        }
        return signStr;
    }

}
